package cn.buk.api.ctrip.service;

import cn.buk.api.ctrip.dto.share.*;
import cn.buk.util.XmlUtil;
import com.ctrip.openapi.java.base.HttpAccessAdapter;
import com.ctrip.openapi.java.utils.GzipUtil;
import org.apache.commons.codec.binary.Base64;

import javax.xml.bind.*;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by yfdai on 16/1/5.
 */
public class IntlLowPriceServiceImpl implements IntlLowPriceService {

//    接口地址：
//    http://Intlflightapi.ctrip.com/Intlflightapi/OpenAPI.asmx
//    https://Intlflightapi.ctrip.com/Intlflightapi/OpenAPI.asmx （https协议）
    private static final String OPEN_API_URL = "http://Intlflightapi.ctrip.com/Intlflightapi/OpenAPI.asmx";


    /**
     * 是否在控制台输出接口请求和响应的xml
     */
    private final boolean outputXml;

    public IntlLowPriceServiceImpl() {
        this.outputXml = false;
    }

    public IntlLowPriceServiceImpl(boolean outputXml) {
        this.outputXml = outputXml;
    }


    private String execApiRequest(String userId, String password, int apiType, String requestContent, String urlString) {
        String responseXml = HttpAccessAdapter.SendRequestToShareIntl(userId, password, apiType, requestContent, urlString);

        byte[] bytes;
        try {
            bytes = new Base64().decode(responseXml.getBytes());
            bytes = GzipUtil.unGZip(bytes);
            responseXml = new String(bytes, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return responseXml;
    }


    public <T>T convertXmlTo(String xml, Class<T> c) {
        T response = null;
        try {
            JAXBContext jc = JAXBContext.newInstance(c);
            Unmarshaller m = jc.createUnmarshaller();
            Object obj = m.unmarshal(new StringReader(xml));

            if (obj.getClass() == JAXBElement.class) obj = ((JAXBElement)obj).getValue();

            response= (T) obj;

        } catch (JAXBException e) {
            System.out.println(e.getMessage());
            System.out.println(xml);
        }

        return response;
    }


    /**
     * 低价看板接口
     * @param userId
     * @param password
     * @param request
     * @return
     */
    public ArrayOfIntlLowPriceResponse searchLowPrice(String userId, String password, IntlLowPriceRequest request) {
        String content = XmlUtil.convertToXml(request, IntlLowPriceRequest.class);

        if (this.outputXml) {
            System.out.println(content);
        }

        String responseXml = execApiRequest(userId, password, 0, content, "http://Intlflightapi.ctrip.com/Intlflightapi/LowPrice.asmx");

        if (this.outputXml) {
            System.out.println(responseXml);
        }

        return convertXmlTo(responseXml, ArrayOfIntlLowPriceResponse.class);
    }

    @Override
    public OwFareResponse searchIntlOwFareInfo(String username, String password, IntlOwFareInfo owFareInfo) {
        OwFareRequest request = new OwFareRequest();
        request.getOwFareInfoList().add(owFareInfo);

        String content = XmlUtil.convertToXml(request, OwFareRequest.class, IntlOwFareInfo.class);

        if (this.outputXml) {
            System.out.println(content);
        }

//        c. ApiType：   1表示私有OW运价新增，2表示私有OW删除
//        3表示私有RT运价新增，4表示私有RT删除
//        9表示公布佣金政策新增，10表示公布运价政策删除

        String responseXml = execApiRequest(username, password, PRIVATE_OW_POLICY_READ, content, OPEN_API_URL);

        if (this.outputXml) {
            System.out.println(responseXml);
        }

        return convertXmlTo(responseXml, OwFareResponse.class);

//        return responseXml;
    }

    @Override
    public IntlOwFareInfo searchOwFareByFareId(String username, String password, long fareId) {
        IntlOwFareInfo owFareInfo = new IntlOwFareInfo();
        owFareInfo.setFareId(fareId + "");
        owFareInfo.setMinPax(1);
        owFareInfo.setMaxPax(9);
        owFareInfo.setSalesPrice(1);

        OwFareResponse response = searchIntlOwFareInfo(username, password, owFareInfo);

        if (response == null) throw new RuntimeException("OwFareResponse is null.");

        if (response.getFareInfos().size() < 1)
            return null;
        else
            return response.getFareInfos().get(0);
    }

    @Override
    public OpenApiResponse adjustOwFareProfit(String username, String password, long fareId, int profit) {
        IntlOwFareInfo owFareInfo = new IntlOwFareInfo();
        owFareInfo.setFareId(fareId + "");
        owFareInfo.setProfit(profit);

        OwFareRequest request = new OwFareRequest();
        request.getOwFareInfoList().add(owFareInfo);

        String content = XmlUtil.convertToXml(request, OwFareRequest.class, IntlOwFareInfo.class);

        if (this.outputXml) {
            System.out.println(content);
        }

        String responseXml = execApiRequest(username, password, PRIVATE_OW_POLICY_PRICE_UPDATE, content, OPEN_API_URL);

        if (this.outputXml) {
            System.out.println(responseXml);
        }

        return convertXmlTo(responseXml, OpenApiResponse.class);
//        return null;
    }

    @Override
    public RtFareResponse searchIntlRtFareInfo(String username, String password, IntlRtFareInfo rtFareInfo) {
        RtFareRequest request = new RtFareRequest();
        request.getRtFareInfoList().add(rtFareInfo);

        String content = XmlUtil.convertToXml(request, RtFareRequest.class, IntlRtFareInfo.class);

        if (this.outputXml) {
            System.out.println(content);
        }

        String responseXml = execApiRequest(username, password, PRIVATE_RT_POLICY_READ, content, OPEN_API_URL);

        if (this.outputXml) {
            System.out.println(responseXml);
        }

        return convertXmlTo(responseXml, RtFareResponse.class);
    }

    @Override
    public IntlRtFareInfo searchRtFareByFareId(String username, String password, long fareId) {
        IntlRtFareInfo fareInfo = new IntlRtFareInfo();
        fareInfo.setFareId(fareId + "");
        fareInfo.setMinPax(1);
        fareInfo.setMaxPax(9);
        fareInfo.setSalesPrice(1);

        RtFareResponse response = searchIntlRtFareInfo(username, password, fareInfo);

        if (response == null) throw new RuntimeException("RtFareResponse is null.");

        if (response.getFareInfos().size() < 1)
            return null;
        else
            return response.getFareInfos().get(0);
    }

    @Override
    public OpenApiResponse adjustRtFareProfit(String username, String password, long fareId, int profit) {
        IntlRtFareInfo fareInfo = new IntlRtFareInfo();
        fareInfo.setFareId(fareId + "");
//        owFareInfo.setMinPax(1);
//        owFareInfo.setMaxPax(9);
//        owFareInfo.setSalesPrice(1);
        fareInfo.setProfit(profit);


        RtFareRequest request = new RtFareRequest();
        request.getRtFareInfoList().add(fareInfo);

        String content = XmlUtil.convertToXml(request, RtFareRequest.class, IntlRtFareInfo.class);

        if (this.outputXml) {
            System.out.println(content);
        }

        String responseXml = execApiRequest(username, password, PRIVATE_RT_POLICY_PRICE_UPDATE, content, OPEN_API_URL);

        if (this.outputXml) {
            System.out.println(responseXml);
        }

        return convertXmlTo(responseXml, OpenApiResponse.class);
    }

    @Override
    public PublishFareResponse searchIntlPubFareInfo(String username, String password, IntlPublishFareInfo fareInfo) {
        IntlPubFareRequest request = new IntlPubFareRequest();
        request.getPubFareInfoList().add(fareInfo);

        String content = XmlUtil.convertToXml(request, IntlPubFareRequest.class, IntlPublishFareInfo.class);

        if (this.outputXml) {
            System.out.println(content);
        }

        String responseXml = execApiRequest(username, password, PUBLIC_POLICY_READ, content, OPEN_API_URL);

        if (this.outputXml) {
            System.out.println(responseXml);
        }

        return convertXmlTo(responseXml, PublishFareResponse.class);

//        return responseXml;
    }

    @Override
    public OpenApiResponse createIntlOwFareInfo(String username, String password, IntlOwFareInfo owFareInfo) {
        List<IntlOwFareInfo> owFareInfos = new ArrayList<>();
        owFareInfos.add(owFareInfo);

        return createIntlOwFareInfo(username, password, owFareInfos);
    }

    @Override
    public OpenApiResponse createIntlOwFareInfo(String username, String password, List<IntlOwFareInfo> owFareInfos) {
        OwFareRequest request = new OwFareRequest();
        request.getOwFareInfoList().addAll(owFareInfos);

        String content = XmlUtil.convertToXml(request, OwFareRequest.class, IntlOwFareInfo.class);
        System.out.println(content);

//        c. ApiType：   1表示私有OW运价新增，2表示私有OW删除
//        3表示私有RT运价新增，4表示私有RT删除
//        9表示公布佣金政策新增，10表示公布运价政策删除

        String responseXml = execApiRequest(username, password, 1, content, OPEN_API_URL);

        return convertXmlTo(responseXml, OpenApiResponse.class);
    }

    @Override
    public OpenApiResponse createIntlRtFareInfo(String username, String password, IntlRtFareInfo rtFareInfo) {
        List<IntlRtFareInfo> rtFareInfos = new ArrayList<>();
        rtFareInfos.add(rtFareInfo);

        return createIntlRtFareInfo(username, password, rtFareInfos);
    }

    @Override
    public OpenApiResponse createIntlRtFareInfo(String username, String password, List<IntlRtFareInfo> rtFareInfos) {
        RtFareRequest request = new RtFareRequest();
        request.getRtFareInfoList().addAll(rtFareInfos);

        String content = XmlUtil.convertToXml(request, RtFareRequest.class, IntlRtFareInfo.class);
//        System.out.println(content);

//        c. ApiType：   1表示私有OW运价新增，2表示私有OW删除
//        3表示私有RT运价新增，4表示私有RT删除
//        9表示公布佣金政策新增，10表示公布运价政策删除

        String responseXml = execApiRequest(username, password, 3, content, OPEN_API_URL);

        return convertXmlTo(responseXml, OpenApiResponse.class);
    }

    @Override
    public OpenApiResponse createIntlPubFareInfo(String username, String password, IntlPublishFareInfo pubFare) {
        IntlPubFareRequest request = new IntlPubFareRequest();
        request.getPubFareInfoList().add(pubFare);

        String content = XmlUtil.convertToXml(request, IntlPubFareRequest.class);
//        System.out.println(content);

//        c. ApiType：   1表示私有OW运价新增，2表示私有OW删除
//        3表示私有RT运价新增，4表示私有RT删除
//        9表示公布佣金政策新增，10表示公布运价政策删除

        String responseXml = execApiRequest(username, password, 9, content, OPEN_API_URL);

        return convertXmlTo(responseXml, OpenApiResponse.class);
    }
}
